#!/usr/bin/python3

import os
import sys
import csv
import time
import pathlib


def run_mpstat():
    os.system('ssh -f agent1 "cd /home/shy/; mpstat 1 > mpstat.txt &"')
    os.system('ssh -f agent1 "cd /home/shy/; sh show_power.sh &"')


def get_mpstat(sql_id: int):
    print("get mpstat")
    os.system('ssh -f agent1 "cd /home/shy; sh kill_mpstat.sh"')
    os.system('ssh -f agent1 "cd /home/shy; sh kill_power.sh"')
    os.system("rm -f mpstat" + str(sql_id) + ".txt")
    os.system("rm -f power" + str(sql_id) + ".txt")
    path = pathlib.Path("mpstat" + str(sql_id) + ".txt")
    for i in range(5):
        if not path.is_file():
            print("no mpstat.txt")
            os.system("scp agent1:/home/shy/mpstat.txt ./mpstat" + str(sql_id) + ".txt")
            time.sleep(1)
        else:
            break
    path = pathlib.Path("power" + str(sql_id) + ".txt")
    for i in range(5):
        if not path.is_file():
            print("no power.txt")
            os.system("scp agent1:/home/shy/power.txt ./power" + str(sql_id) + ".txt")
            time.sleep(1)
        else:
            break


def run_single_sql(sql_id: int):
    query_map = [82, 57, 53, 71, 84]
    setting_file = "sql" + str(sql_id) + ".sql_hive.setting"

    '''
    if sql_id <= 5 and sql_id >= 1:
        sql_id = query_map[sql_id - 1]
    else:
        setting_file = "common.setting"
    '''
    setting_file = "/home/bigdata_auto/test/hive/conf/sql/sql_setting/common.setting"

    run_sql = "/usr/local/hive/bin/beeline -n root -u jdbc:hive2://server1:10000 -i ../settings/" + setting_file + \
              " -f /home/bigdata_auto/test/hive/conf/sql/tpcds_sql_file/sql" + str(sql_id) + ".sql" + " &> result_" + str(sql_id) + ".txt"
    #  run_sql = "/usr/local/hive/bin/beeline -n root -u jdbc:hive2://server1:10000 -i ../settings/" + setting_file + \
    #          " -f ../tpcds_sql_file/sql1.sql"
    os.system(run_sql)
    #print(run_sql)


def set_container_size(size: int):
    os.system("cp /home/bigdata_auto/test/hive/conf/sql/sql_setting/common.setting.bak /home/bigdata_auto/test/hive/conf/sql/sql_setting/common.setting")
    str1 = "set hive.tez.container.size=" + str(size) + ";"
    os.system('echo "' + str1 + '" >> /home/bigdata_auto/test/hive/conf/sql/sql_setting/common.setting')


def clear_cache():
    os.system("echo 3 > /proc/sys/vm/drop_caches")


def get_avg_power() -> float:
    power = []
    avg_power = 0
    with open("power10.txt", "r") as f:
        for line in f.readlines():
            power.append(int(line.strip().split()[-1]))
    if len(power) > 0:
        avg_power = sum(power) / len(power)
    return avg_power


def get_avg_util() -> float:
    util = []
    avg_util = 0
    with open("mpstat10.txt", "r") as f:
        for line in f.readlines():
            if "all" in line:
                util.append(100 - float(line.strip().split()[-1]))
    if len(util) > 0:
        avg_util = sum(util) / len(util)
    return avg_util


def change_governor(governor: str):
    for i in range(3):
        print("change governot to " + governor)
        os.system('ssh ' + 'agent' + str(i + 1) + ' "cpupower frequency-set -g ' + governor + ' 1>/dev/null"')


def set_freq_step(freq_step: int):
    print("set freq_step:%u" % freq_step)
    for i in range(3):
        os.system('ssh ' + 'agent' + str(i + 1) + ' "echo ' + str(
            freq_step) + ' > /sys/devices/system/cpu/cpufreq/seep/freq_step"')


def run_od_load():
    os.system('ssh -f ' + 'agent1' + ' "cd /home/j00521119/bcc; python3 od_load.py &"')


def stop_od_load():
    os.system('ssh -f ' + 'agent1' + ' "cd /home/j00521119/bcc; sh stop_od_load.sh"')


def run_od_freq():
    os.system('ssh -f ' + 'agent1' + ' "cd /home/j00521119/bcc; python3 od_freq.py &"')


def stop_od_freq():
    os.system('ssh -f ' + 'agent1' + ' "cd /home/j00521119/bcc; sh stop_od_freq.sh"')


def write_csv(governor: str, sql_time: float, power: float, util: float):
    with open("./result.csv", 'a', newline='') as f:
        csv_write = csv.writer(f)
        row = []
        row.append(governor)

        row.append(f'{sql_time:.3f}')
        row.append(f'{power:.3f}')
        row.append(f'{util:.3f}')

        csv_write.writerow(row)


def cpu_set():
    for i in range(3):
        os.system('ssh ' + 'agent' + str(i + 1) + ' "echo 0-127 > /sys/fs/cgroup/cpuset/tg1/cpuset.cpus"')
        os.system('ssh ' + 'agent' + str(i + 1) + ' "echo 0-63 > /sys/fs/cgroup/cpuset/tg1/cpuset.preferred_cpus"')
        os.system('ssh ' + 'agent' + str(i + 1) + ' "echo 0-3 > /sys/fs/cgroup/cpuset/tg1/cpuset.mems"')
        os.system('ssh ' + 'agent' + str(i + 1) + ' "echo 1 > /proc/sys/kernel/phase/enabled"')


def cpu_unset():
    for i in range(3):
        os.system('ssh ' + 'agent' + str(i + 1) + ' "echo 0-127 > /sys/fs/cgroup/cpuset/tg1/cpuset.cpus"')
        os.system('ssh ' + 'agent' + str(i + 1) + ' "echo 0-127 > /sys/fs/cgroup/cpuset/tg1/cpuset.preferred_cpus"')
        os.system('ssh ' + 'agent' + str(i + 1) + ' "echo 0-3 > /sys/fs/cgroup/cpuset/tg1/cpuset.mems"')
        os.system('ssh ' + 'agent' + str(i + 1) + ' "echo 0 > /proc/sys/kernel/phase/enabled"')


def run_mem_process(index: int):
    os.system('ssh -f ' + 'agent1' + ' "cd /home/j00521119/bigdata/get_data; ./mem_process.py ' + str(index) + ' &"')


def get_mon_data(index: int):
    os.system('ssh -f ' + 'agent1' + ' "cd /home/j00521119/bigdata/get_data; cp mon_data.txt mon_data_0' + str(
        index) + '.txt"')
    time.sleep(10)


def enable_mpc():
    os.system('ssh -f ' + 'agent1' + ' ipmitool raw 0x30 0x93 0xdb 0x07 0x00 0x5a 0x33 0x00 0x01 0x00 0x01')


def disable_mpc():
    os.system('ssh -f ' + 'agent1' + ' ipmitool raw 0x30 0x93 0xdb 0x07 0x00 0x5a 0x33 0x00 0x01 0x00 0x00')

def change_to_seep():
    for i in range(3):
        os.system('ssh ' + 'agent' + str(i + 1) + ' "echo 1 > /sys/devices/system/cpu/cpufreq/conservative/fast_mode"')

def unable_seep():
    for i in range(3):
        os.system('ssh ' + 'agent' + str(i + 1) + ' "echo 0 > /sys/devices/system/cpu/cpufreq/conservative/fast_mode"')

if __name__ == '__main__':
    sql_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    #print(time.ctime())

    governor_list = ["performance", "conservative", "conservative"]

    count = 0
    #    size_list = [40960, 30720, 20480, 15360, 10240]
    size_list = [40960, 30720, 20480]

    while (1):
        #print(count)
        size = size_list[int(count / len(governor_list)) % len(size_list)]
        print(size)
        #        size = 20480

        index = count % len(governor_list)
        governor = governor_list[index]

        #change_governor(governor)

        #
        if governor != 'performance':
            governor += str(index)
            change_to_seep()
            if index == 2:
                cpu_set()
                print(governor)
            else:
                cpu_unset()
                print(governor)
        else:
            cpu_unset()
            print(governor)



        clear_cache()
        set_container_size(size)
        run_mpstat()
        time_start = time.time()
        for i in sql_list:
            if i == 14:
                continue
            print("run sql" + str(i))
            run_single_sql(i)
        
        time_end = time.time()
        time_elapsed = time_end - time_start
        
        get_mpstat(10)
        avg_power = get_avg_power()
        avg_util = get_avg_util()
        write_csv(governor, time_elapsed, avg_power, avg_util)

        count += 1
        if count >= 30:
            break


